﻿using System;
using Bakındur.Hook;
using System.Windows.Forms;
using Bakındur.Theming;
using Bakındur.Properties;
using System.Drawing;
using System.Linq;

namespace Bakındur
{
    public class Sozluk : IDisposable
    {
        System.Windows.Forms.Timer timer;
        MainWindow win;
        bool ctrlDown = false;
        KeyboardHook kbHook;

        public string GrabbedWords { get; set; }

        #region Contructor- Deconstructor
        public Sozluk()
        {
            win = new MainWindow();

            timer = new System.Windows.Forms.Timer { Interval = 400 };
            timer.Tick += (object sender, EventArgs e) => { timer.Enabled = false; };
            CreateHook();
        }

        public void Dispose()
        {
            Unhook();
        }

        public void CreateHook()
        {
            HookManager.MouseClickExt += HookManager_MouseClickExt;
            kbHook = new KeyboardHook(KeyboardHook.Parameters.PassAllKeysToNextApp);
            kbHook.KeyIntercepted += kbHook_KeyIntercepted;
            kbHook.KeyUp += kbHook_KeyUp;
            kbHook.KeyDown += new KeyEventHandler(kbHook_KeyDown);
        }

        void kbHook_KeyDown(object sender, KeyEventArgs e)
        {
            ctrlDown = true;
            e.Handled = true;
        }

        void kbHook_KeyUp(object sender, KeyEventArgs e)
        {
            ctrlDown = false;
        }

        public void Unhook()
        {
            if (kbHook != null)
            {
                kbHook.Dispose();
                kbHook = null;
            }
            HookManager.MouseClickExt -= HookManager_MouseClickExt;
        }
        #endregion

        void kbHook_KeyIntercepted(KeyboardHook.KeyboardHookEventArgs e)
        {
            if (Properties.Settings.Default.DoubleCtrlActivation && e.KeyCode == KeyboardHook.LCONTROL_KEY || e.KeyCode == KeyboardHook.RCONTROL_KEY)
            {
                if (timer.Enabled)
                {
                    if (win.Visible)
                        win.HideForm();
                    else
                    {
                        GrabWords();
                        ShowResult();
                    }

                    timer.Enabled = false;
                }
                else
                    timer.Enabled = true;
            }
        }

        void HookManager_MouseClickExt(object sender, MouseEventExtArgs e)
        {
            if (ctrlDown && Properties.Settings.Default.BabylonStyleActivation && e.Button == MouseButtons.Right)
            {
                GrabWordsMouse(e.Location);
                ShowResult();
                e.Handled = true;
            }
        }

        private bool GrabWords()
        {
            bool grabbed = false;
            Clipboard.Clear();
            SendKeys.SendWait("^c");
            if (Clipboard.ContainsText())
            {
                GrabbedWords = Clipboard.GetText();
                GrabbedWords = GrabbedWords.Trim();
                grabbed = !string.IsNullOrEmpty(GrabbedWords);
            }
            return grabbed;
        }

        private bool GrabWordsMouse(Point location)
        {
            OCR.OcrReader reader = new OCR.OcrReader();
            var readList = reader.Read(CaptureScreenShot(location));

            var lineCount = readList.GroupBy(x => x.LineIndex).Count();

            var clean = from x in readList
                        where
                        x.Text != "~" &&
                        !x.Text.Contains('!') &&
                        !x.Text.Contains('+') &&
                        !x.Text.Contains('%') &&
                        !x.Text.Contains('&') &&
                        !x.Text.Contains('/') &&
                        !x.Text.Contains('(') &&
                        !x.Text.Contains(')') &&
                        !x.Text.Contains('=') &&
                        !x.Text.Contains('?') &&
                        !x.Text.Contains('-') &&
                        !x.Text.Contains('#') &&
                        !x.Text.Contains('[') &&
                        !x.Text.Contains(']') &&
                        !x.Text.Contains('{') &&
                        !x.Text.Contains('}') &&
                        !x.Text.Contains('*') &&
                        !x.Text.Contains('_') &&
                        !x.Text.Contains('\\') &&
                        x.LineIndex == lineCount / 2
                        select x;
            var result = (from x in clean
                          where x.Confidence == clean.Min(y => y.Confidence)
                          select x).FirstOrDefault();
            if (result != null)
            {
                GrabbedWords = result.Text;
                return true;
            }

            return false;
        }

        private Bitmap CaptureScreenShot(Point mousePos)
        {
            Size size = new Size(200, 50);
            Bitmap bitmap = new Bitmap(size.Width, size.Height);
            using (Graphics gr = Graphics.FromImage(bitmap))
            {
                gr.CopyFromScreen(new Point(mousePos.X - size.Width / 2, mousePos.Y - size.Height / 2), Point.Empty, size);
            }

            Bitmap bigBitmap = new Bitmap(bitmap, new Size(size.Width * 3, size.Height * 3));
            return bigBitmap;
        }

        public void ShowResult()
        {
            win.ShowResult(GrabbedWords);
            GrabbedWords = string.Empty;
        }

        public void ApplyTheme()
        {
            win.ApplyTheme(ThemeCollection.Current.GetTheme(Properties.Settings.Default.Theme));
        }
    }
}

